<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // for...in for...of  和 数组的forEach 有什么区别?
    // for...in for...of 是JS基础语法, 不仅可以遍历数组,以后也可以用于字符串,对象,Map,Set,伪数组
    // 作为数组自带的forEach方法,一般情况下仅数组可用，没有办法与break、continue以及return配合使用


    // 数组的遍历方法

    // forEach()  
    // map()
    // filter() 
    // find()
    // findIndex()
    // some()
    // every()
    // reduce();;



    // 模拟封装

    // 封装
    /* function myForEach(list,fn) {
        console.log(list,fn);
        // function fn(item, index, array) { // 函数定死
        //     console.log(item, index, array);
        // }
        // var list = [1, 4, 7, 8, 5, 2, 3, 6, 9];  //数组定死
        for (var i in list) {
            i = Number(i); // 循环的当前下标
            fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
        }
    }

    myForEach([1,4,7],function(item,index){
        console.log(item,index);
    });
    myForEach([2,5,8],function(a,b){
        console.log(a,b);
    }); */


    /*  function myMap(list, fn) {
         console.log(list, fn);
         // function fn(item, index, array) { // 函数定死
         //     console.log(item, index, array);
         // }
         // var list = [1, 4, 7, 8, 5, 2, 3, 6, 9];  //数组定死
 
         var arr = [];
         for (var i in list) {
             i = Number(i); // 循环的当前下标
             var result = fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
             arr.push(result);
         }
         return arr;
     }
 
     var result = myMap([1, 4, 7], function (item, index) {
         console.log(item, index);
         return item * 10;
     });
     console.log(result); */

    // 面向对象 => 原型对象
    // Array.prototype.myForEach = function(callback){

    // } 


    // debugger;
    // function myFilter(list,fn) {
    //     console.log(list,fn);

    //     var arr = [];
    //     for (var i in list) {
    //         i = Number(i); // 循环的当前下标
    //         // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
    //         var result = fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
    //         if(!!result){
    //             arr.push(list[i]);
    //         }
    //     }
    //     return arr;
    // }

    // var result = myFilter([1,4,7],function(item,index){
    //     console.log(item,index);
    //     return item % 2 == 0;
    // });
    // console.log(result);


    /* function myFind(list, fn) {
        console.log(list, fn);

        var arr = [];
        for (var i in list) {
            i = Number(i); // 循环的当前下标
            // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
            var result = fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
            if (!!result) {
               return list[i];
            }
        }
        
    }

    function myFindIndex(list, fn) {
        console.log(list, fn);

        var arr = [];
        for (var i in list) {
            i = Number(i); // 循环的当前下标
            // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
            var result = fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
            if (!!result) {
               return i;
            }
        }
        return -1;
    }

    var result = myFind([1, 4, 7, 8, 5, 2], function (item, index) {
        console.log(item, index);
        return item % 2 == 0;
    });
    console.log(result); */



   /*  function mySome(list, fn) {
        console.log(list, fn);

        var flag = false;
        for (var i in list) {
            i = Number(i); // 循环的当前下标
            // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
            var result = fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
            if (!!result) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    function myEvery(list, fn) {
        console.log(list, fn);

        var flag = true; // 假设都满足
        for (var i in list) {
            i = Number(i); // 循环的当前下标
            // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
            var result = fn(list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
            if (!!result == false) { // 如果存在不满足的
                flag = false; 
                break;
            }
        }
        return flag;
    }


    var result = mySome([1, 4, 7, 8, 5, 2], function (item, index) {
        console.log(item, index);
        // return item % 2 == 0;
        return item > 10;
    });
    console.log(result); */




    function myReduce(list, fn,initValue) {
        console.log(list, fn);

        if(initValue!= undefined){ // 有初始值
            var sum = initValue;  
            for (var i in list) {
                i = Number(i); // 循环的当前下标
                // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
                sum = fn( sum, list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
            
            }
            return sum;
        }else{
            var sum = list[0];   // 如果没有初始值,默认将数组的第一个元素作为初始值,从第二个开始遍历
            for (var i in list) {
                if(i == 0) continue;
                i = Number(i); // 循环的当前下标
                // filter传入的回调函数要求返回条件表达式(如果非条件表达式 隐式转布尔值)
                sum = fn( sum, list[i], i, list); // 实际参数 (循环的当前元素, 下标 原数组)
            
            }
            return sum;
        }
        
    }

    var result = myReduce([1, 4, 7, 8, 5, 2], function (prev,item, index) {
        console.log(prev, item, index);
        return prev + item;
    });
    console.log(result);






</script>

</html>